package org.whatever.aha.zjut.platform.service.project;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.whatever.aha.zjut.base.constant.ErrorCode;
import org.whatever.aha.zjut.base.constant.StatusConstant;
import org.whatever.aha.zjut.base.exception.AppException;
import org.whatever.aha.zjut.platform.dto.project.ProjectDto;
import org.whatever.aha.zjut.platform.dto.project.ProjectMemberDto;
import org.whatever.aha.zjut.platform.entity.competition.CompetitionStaticTags;
import org.whatever.aha.zjut.platform.entity.project.Project;
import org.whatever.aha.zjut.platform.entity.project.ProjectMember;
import org.whatever.aha.zjut.platform.entity.project.ProjectReturnLog;
import org.whatever.aha.zjut.platform.entity.school.ProjectScore;
import org.whatever.aha.zjut.platform.mapper.project.ProjectMapper;
import org.whatever.aha.zjut.platform.mapper.project.ProjectMemberMapper;
import org.whatever.aha.zjut.platform.service.UserRoleService;
import org.whatever.aha.zjut.platform.service.UserService;
import org.whatever.aha.zjut.platform.service.competition.CompetitionService;
import org.whatever.aha.zjut.platform.service.school.JudgeProjectDistributionService;
import org.whatever.aha.zjut.platform.service.school.ProjectScoreService;
import org.whatever.aha.zjut.platform.util.BeanUtil;
import org.whatever.aha.zjut.platform.util.StatusConvertUtil;
import org.whatever.aha.zjut.platform.vo.PageVo;
import org.whatever.aha.zjut.platform.vo.UserRoughInfoVo;
import org.whatever.aha.zjut.platform.vo.academy.HistoryVo;
import org.whatever.aha.zjut.platform.vo.academy.RecommendVo;
import org.whatever.aha.zjut.platform.vo.info.StatusInfoVo;
import org.whatever.aha.zjut.platform.vo.judge.JudgeProjectRoughInfoVo;
import org.whatever.aha.zjut.platform.vo.project.ProjectDetailVo;
import org.whatever.aha.zjut.platform.vo.project.ProjectReturnLogVo;
import org.whatever.aha.zjut.platform.vo.project.ProjectRoughVo;
import org.whatever.aha.zjut.platform.vo.project.ProjectStuRoughVo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Vc
 * @version 1.0
 * @Desc
 * @date 2021/09/15 0:02
 */
@RequiredArgsConstructor
@Service
@Validated
public class ProjectService {
    final ProjectMemberService projectMemberService;
    final ProjectMapper projectMapper;
    final ProjectMemberMapper projectMemberMapper;
    final UserRoleService userRoleService;
    final ProjectReturnLogService projectReturnLogService;
    @Autowired
    @Lazy
    private ProjectScoreService projectScoreService;
    @Autowired
    @Lazy
    private UserService userService;
    @Autowired
    @Lazy
    private CompetitionService competitionService;
    @Autowired
    @Lazy
    private JudgeProjectDistributionService judgeProjectDistributionService;


    /**
     * 创建新的比赛单体信息
     *
     * @param projectDto
     * @param userId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int addProjectAndAuthor(ProjectDto projectDto, int userId, int compId, int stageId){
        Project project = new Project();
//        BeanUtils.copyProperties(projectDto, project);
        //只需要设置这些属性
        project.setProjectName(projectDto.getProjectName());
        project.setProjectGroup(projectDto.getProjectGroup());
        project.setProjectTag(projectDto.getProjectTag());
        project.setProjectSchoolRec(projectDto.getProjectSchoolRec());
        project.setProjectAcademyId(projectDto.getProjectAcademyId());

        project.setStageId(stageId);
        project.setCompId(compId);
        project.setProjectLeaderId(userId);
        project.setProjectCreateTime(new Date());
        projectMapper.insert(project);
        int projectId = project.getProjectId();
        projectMemberService.addProjectMemberByProjectId(userId, projectId, StatusConstant.RANK_LEADER.getCode(), "队长");
        if(projectDto.getMemberDtos() != null && projectDto.getMemberDtos().size() > 0){
            projectDto.getMemberDtos().forEach(memberDto->{
                projectMemberService.addProjectMemberByProjectId(memberDto.getMemberId(), projectId, memberDto.getProjectMemberRank(), memberDto.getProjectMemberJob());
            });
        }
        return project.getProjectId();
    }


    /**
     * 分页获取项目粗略信息
     *
     * @param userId
     * @param compType
     * @param projectStudentStatus
     * @param offset
     * @param pageSize
     * @return
     */
    public List<ProjectStuRoughVo> getProjectRoughPageable(int userId, int compType, Integer projectStudentStatus, int offset, int pageSize){
        return projectMapper.getProjectRoughPageable(userId, compType, projectStudentStatus, offset, pageSize);
    }

    /**
     * 根据项目ID获取项目粗略信息
     *
     * @param projectId
     * @return
     */
    public ProjectRoughVo getProjectRoughVoById(int projectId){
        Project project = projectMapper.selectById(projectId);
        ProjectRoughVo projectRoughVo = new ProjectRoughVo();
        BeanUtils.copyProperties(project, projectRoughVo);
        return projectRoughVo;
    }

    /**
     * 获取项目名
     *
     * @param projectId
     * @return
     */
    public String getProjectNameById(int projectId){
        return (String)projectMapper.selectObjs(new QueryWrapper<Project>().eq("project_id", projectId).select("project_name")).get(0);
    }

    /**
     * 获取项目详细信息
     *
     * @param projectId
     * @return
     */
    public ProjectDetailVo getProjectDetailById(int projectId){
        return projectMapper.getProjectDetailById(projectId);
    }

    /**
     * 根据项目Id更新项目信息
     *
     * @param projectDto
     * @param projectId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int updateProjectByProjectId(ProjectDto projectDto, int userId, int projectId, int compId, int stageId){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }

        if(projectDto.getMemberDtos() != null){

            // 删除所有非队长角色
            projectMemberMapper.delete(new QueryWrapper<ProjectMember>().eq("project_id",projectId).ne("project_member_rank",1));

            // 插入批量信息
            for (ProjectMemberDto projectMemberDto : projectDto.getMemberDtos()) {
                ProjectMember projectMember = new ProjectMember();
                BeanUtils.copyProperties(projectMemberDto, projectMember);
                projectMember.setProjectId(projectId);
                projectMemberMapper.insert(projectMember);
            }
        }

//        //更新项目成员
//        if(projectDto.getMemberDtos() != null && projectDto.getMemberDtos().size() > 0){
//            projectMemberService.updateProjectMembers(projectDto.getMemberDtos(),projectId);
//        }
        //更新项目其他信息
        Project project = new Project();
        BeanUtils.copyProperties(projectDto, project);
        project.setStageId(stageId);
        project.setCompId(compId);
        project.setProjectLeaderId(userId);
        projectMapper.update(project, new QueryWrapper<Project>().eq("project_id",projectId));
        return projectId;
    }

    /**
     * 检查用户是否有项目修改权限,校级管理员和超级管理员可以修改
     *
     * @param userId    用户id
     * @param projectId 项目id
     * @return 是否有修改权限
     */
    public boolean hasPermission(int userId, int projectId) {
        Integer roleByUid = userRoleService.getRoleByUid(userId);
        if(roleByUid.equals(StatusConstant.IDENTITY_SCHOOL_ADMIN) || roleByUid.equals(StatusConstant.IDENTITY_SUPER_ADMIN)){
            return true;
        }
        int creatorUserId = projectMapper.selectOne(new QueryWrapper<Project>().eq("project_id",projectId)).getProjectLeaderId();
        return userId == creatorUserId;
    }

    /**
     * 根据项目ID删除项目
     *
     * @param projectId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int deleteProjectById(int projectId){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }

        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("project_id",projectId);
        updateWrapper.set("project_delete_status", 1);
        return projectMapper.update(null,updateWrapper );
    }

    /**
     * 获得团队负责人Id
     *
     * @param projectId
     * @return
     */
    public Object getLeaderId(int projectId){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        List<Object> lo = projectMapper.selectObjs(new QueryWrapper<Project>().eq("project_id",projectId).select("project_leader_id"));
        return lo.size()>0 ? lo.get(0): null;
    }

    /**
     * 根据竞赛id获得比赛id
     *
     * @param projectId
     * @return
     */
    public Object getCompIdByProjectId(int projectId){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }

        List<Object> lo = projectMapper.selectObjs(new QueryWrapper<Project>().eq("project_id",projectId).select("comp_id"));
        return lo.size()>0 ? lo.get(0): 0;
    }

    /**
     * 根据比赛id获得竞赛id
     *
     * @param compId
     * @return
     */
    public List<Object> getProjectIdByCompId(int compId){
       return projectMapper.selectObjs(new QueryWrapper<Project>().eq("comp_id",compId).select("project_id"));
    }

    /**
     * 获得所有的项目Id
     *
     * @return
     */
    public List<Object> getProjectIds(){
        return projectMapper.selectObjs(new QueryWrapper<Project>().select("project_id"));
    }


    /**
     * 学生提交项目
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int submitProject(int projectId, Integer academyStatus, Integer schoolStatus){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("project_id",projectId);
        updateWrapper.set("project_student_status", StatusConstant.PROJECT_STUDENT_STATUS_SUBMITTED.getCode());
        updateWrapper.set("project_academy_status", academyStatus);
        if (schoolStatus != null) {
            updateWrapper.set("project_school_status", schoolStatus);
        }
        return projectMapper.update(null,updateWrapper );
    }

    /**
     * 获得当前项目学生状态
     *
     * @param projectId
     * @return
     */
    public int getProjectStuStatus(int projectId){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        Object curStuStatus = projectMapper.selectOne(new QueryWrapper<Project>().eq("project_id",projectId)).getProjectStudentStatus();
        return (int) curStuStatus;
    }

    /**
     * 获取某个竞赛某个阶段下所有的项目
     *
     * @param stageId
     * @return
     */
    public List<Project> getProjectsByStageId(int stageId){
        return projectMapper.selectList(new QueryWrapper<Project>().eq("stage_id",stageId));
    }

    /**
     * 分页获取某个竞赛某个阶段下所有的项目
     *
     * @param compId
     * @param stageId
     * @return
     */
    public Map getProjectsByCompIdAndStageIdPageable(int compId, int stageId, int pageNum, int pageSize, Boolean academyThirdPrize){
        Page<Project> projectPage = projectMapper.selectPage(new Page<>(pageNum, pageSize),
                new QueryWrapper<Project>().eq("comp_id", compId)
                        .eq("stage_id", stageId)
                        .eq(academyThirdPrize != null && academyThirdPrize == true, "project_award_id", StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode())
                        .ne(academyThirdPrize == null || academyThirdPrize == false, "project_award_id", StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode())
                        .orderByDesc("project_avg_score"));
        return Map.of("projectList", projectPage.getRecords(), "total", projectPage.getTotal());

    }

    /**
     * 获取某个竞赛下所有的项目
     *
     * @param compId
     * @return
     */
    public List<Project> getProjectsByCompId(int compId){
        return projectMapper.selectList(new QueryWrapper<Project>().eq("comp_id",compId));
    }

    /**
     * 根据project信息更新项目
     *
     * @param project
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int updateProject(Project project){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", project.getProjectId()))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        return projectMapper.updateById(project);
}

    /**
     * 校级管理员修改队伍总分   公示阶段可以修改   覆盖avg_score和project_score
     *
     * @param projectId
     * @param score
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int modifyAvgScore(int projectId, BigDecimal score){
        return projectMapper.update(null,
                new UpdateWrapper<Project>().eq("project_id", projectId)
                        .set("project_score", score)
                        .set("project_avg_score", score));
    }


    /**
     * 根据学院ID获取学院名下特定状态的所有项目数，null为院级管理员需要审核的项目总数，2为未审核的数量
     *
     * @param academyId
     * @param projectSupposeSubmit
     * @return
     */
    public int getProjectNumByAcademyIdAndStatus(int academyId, Integer projectSupposeSubmit, int compId, int stageId, Boolean isNormal){
        return projectMapper.getProjectNumByAcademyIdAndStatus(academyId, projectSupposeSubmit, compId, stageId, isNormal);
    }

    /**
     * 根据学院ID获取学院名下省级推荐项目数
     *
     * @param stageId
     * @param academyId
     * @return
     */
    public int getProvinceProjectNum(int stageId, int academyId){
        return projectMapper.getProvinceProjectNum(stageId, academyId);
    }

    /**
     * 根据学院ID获取学院名下直推三等奖推荐项目数
     *
     * @param stageId
     * @param academyId
     * @return
     */
    public int getAcademyThirdPrizeProjectNum(int stageId, int academyId){
        return projectMapper.getAcademyThirdPrizeProjectNum(stageId, academyId);
    }

    /**
     * 院级管理员把项目退回修改
     *
     * @param projectId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int academyReturnForModify(int projectId, String comment, int userId){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        Project project = projectMapper.selectById(projectId);
        ProjectReturnLog projectReturnLog = this.convertCommentToProjectReturnLog(project, comment, userId);
        projectReturnLogService.addRerutnLog(projectReturnLog);
        project.setProjectStudentStatus(StatusConstant.PROJECT_STUDENT_STATUS_RETURN.getCode());
        project.setProjectAcademyStatus(StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_RETURN_FOR_MODIFY.getCode());
        return projectMapper.updateById(project);
    }

    /**
     * 校级管理员把项目退回修改
     *
     * @param projectId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int SchoolReturnModify(int projectId, String comment, int userId){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        Project project = projectMapper.selectById(projectId);
        ProjectReturnLog projectReturnLog = this.convertCommentToProjectReturnLog(project, comment, userId);
        projectReturnLogService.addRerutnLog(projectReturnLog);
        //省级直推项目的话是否省级直推改为否
        if(StatusConstant.PROJECT_IS_PROVINCE_REC.getCode().equals(project.getProjectProvinceRec())){
            project.setProjectProvinceRec(StatusConstant.PROJECT_IS_NOT_PROVINCE_REC.getCode() == 1);
        }
        //项目校管理员视角置为退回修改，院级管理员视角置为退回修改，学生置为退回修改
        project.setProjectSchoolStatus(StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_RETURN_FOR_MODIFY.getCode());
        project.setProjectAcademyStatus(StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_RETURN_FOR_MODIFY.getCode());
        project.setProjectStudentStatus(StatusConstant.PROJECT_STUDENT_STATUS_RETURN.getCode());
        return projectMapper.updateById(project);
    }


    /**
     * 院级管理员获得未推荐项目，未审核排先
     *
     * @param academyId
     * @param compId
     * @param stageId
     * @return
     */
    public List<RecommendVo> getUnrecProjects(int academyId, int compId, int stageId){
//        List<Project> projects = projectMapper.selectUnRecProjectNum(StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode(), StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_WAIT_FOR_JUDGE.getCode(), StatusConstant.PROJECT_NOT_DELETE.getCode(), compId, stageId, academyId);
        List<Project> projects = projectMapper.selectList(new QueryWrapper<Project>()
                .eq("project_delete_status",StatusConstant.PROJECT_NOT_DELETE.getCode())
                .eq("comp_id", compId)
                .eq("stage_id", stageId)
                .eq("project_academy_id", academyId)
                .ne("project_suppose_submit", StatusConstant.PROJECT_ALREADY_SUPPOSE_SUBMIT.getCode() == 1)
                .ne("project_school_rec", StatusConstant.PROJECT_IS_SCHOOL_COMMUNITY_REC.getCode() == 1)
                .ne("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode() == 1)
                .ne("project_academy_status", StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_INVISIBLE.getCode())
                .ne("project_award_id", StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode())
                .orderByAsc("project_academy_status"));
        List<RecommendVo> recommendVoList = new ArrayList<>();
        projects.forEach(project -> {
            RecommendVo recommendVo = this.convertProjectToRecommandVo(project);
            recommendVoList.add(recommendVo);
        });
        return recommendVoList;
    }

    /**
     * 院级管理员获得普通推荐项目
     *
     * @param academyId
     * @param compId
     * @param stageId
     * @return
     */
    public List<RecommendVo> getNormalProjects(int academyId, int compId, int stageId){
        List<Project> projects = projectMapper.selectList(new QueryWrapper<Project>()
                .eq("project_suppose_submit", StatusConstant.PROJECT_ALREADY_SUPPOSE_SUBMIT.getCode() == 1)
                .eq("project_delete_status",StatusConstant.PROJECT_NOT_DELETE.getCode() == 1)
                .eq("comp_id", compId)
                .eq("stage_id", stageId)
                .eq("project_academy_id", academyId)
                .ne("project_school_rec", StatusConstant.PROJECT_IS_SCHOOL_COMMUNITY_REC.getCode() == 1)
                .ne("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode() == 1));
        List<RecommendVo> recommendVoList = new ArrayList<>();
        projects.forEach(project -> {
            RecommendVo recommendVo = this.convertProjectToRecommandVo(project);
            recommendVoList.add(recommendVo);
        });
        return recommendVoList;
    }

    /**
     * 院级管理员获得院级自评三等奖项目
     *
     * @param academyId
     * @param compId
     * @param stageId
     * @return
     */
    public List<RecommendVo> getAcademyThirdPrizeProjects(int academyId, int compId, int stageId){
        List<Project> projects = projectMapper.selectList(new QueryWrapper<Project>()
                .eq("project_award_id", StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode())
                .eq("project_delete_status",StatusConstant.PROJECT_NOT_DELETE.getCode() == 1)
                .eq("comp_id", compId)
                .eq("stage_id", stageId)
                .eq("project_academy_id", academyId));
        List<RecommendVo> recommendVoList = new ArrayList<>();
        projects.forEach(project -> {
            RecommendVo recommendVo = this.convertProjectToRecommandVo(project);
            recommendVoList.add(recommendVo);
        });
        return recommendVoList;
    }

    /**
     * 院级管理员获取省级推荐项目
     *
     * @param academyId
     * @param compId
     * @param stageId
     * @return
     */
    public List<RecommendVo> getProvinceRecProjects(int academyId, int compId, int stageId){
        List<Project> projects = projectMapper.selectList(new QueryWrapper<Project>()
                .eq("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode() == 1)
                .eq("project_delete_status",StatusConstant.PROJECT_NOT_DELETE.getCode() == 1)
                .eq("comp_id", compId)
                .eq("stage_id", stageId)
                .eq("project_academy_id", academyId));
        List<RecommendVo> recommendVoList = new ArrayList<>();
        projects.forEach(project -> {
            RecommendVo recommendVo = this.convertProjectToRecommandVo(project);
            recommendVoList.add(recommendVo);
        });
        return recommendVoList;
    }

    /**
     * 院级管理员获取校团委推荐项目
     *
     * @param academyId
     * @param compId
     * @param stageId
     * @return
     */
    public List<RecommendVo> getSchoolCommunityRecProjects(int academyId, int compId, int stageId){
        List<Project> projects = projectMapper.selectList(new QueryWrapper<Project>()
                .eq("project_school_rec", StatusConstant.PROJECT_IS_SCHOOL_COMMUNITY_REC.getCode() == 1)
                .eq("project_delete_status",StatusConstant.PROJECT_NOT_DELETE.getCode() == 1)
                .eq("comp_id", compId)
                .eq("stage_id", stageId)
                .eq("project_academy_id", academyId));
        List<RecommendVo> recommendVoList = new ArrayList<>();
        projects.forEach(project -> {
            RecommendVo recommendVo = this.convertProjectToRecommandVo(project);
            recommendVoList.add(recommendVo);
        });
        return recommendVoList;
    }

    /**
     * 构造项目状态-学院管理员视角返回类型
     *
     * @param statusId
     * @return
     */
    public StatusInfoVo getAcademyStatusInfoVoByStatusId(int statusId){
        return new StatusInfoVo(statusId, StatusConvertUtil.convertProjectAcademyStatus(statusId));
    }

    /**
     * 构造项目状态-校级管理员视角返回类型
     *
     * @param statusId
     * @return
     */
    public StatusInfoVo getSchoolStatusInfoVoByStatusId(int statusId){
        return new StatusInfoVo(statusId, StatusConvertUtil.convertProjectSchoolStatus(statusId));
    }

    /**
     * 转换项目->推荐类型
     *
     * @param project
     * @return
     */
    public RecommendVo convertProjectToRecommandVo(Project project){
        RecommendVo recommendVo = new RecommendVo();
        BeanUtils.copyProperties(project, recommendVo);
        recommendVo.setProjectSchoolStatusInfo(getSchoolStatusInfoVoByStatusId(project.getProjectSchoolStatus()));
        recommendVo.setProjectAcademyStatusInfo(getAcademyStatusInfoVoByStatusId(project.getProjectAcademyStatus()));
        recommendVo.setProjectLeaderInfo(userService.getStuRoughInfoById(project.getProjectLeaderId()));
        return recommendVo;
    }

    /**
     * 转换项目->获奖历史类型
     *
     * @param project
     * @return
     */
    public HistoryVo convertProjectToHistoryVo(Project project){
        HistoryVo historyVo = new HistoryVo();
        BeanUtils.copyProperties(project, historyVo);
        historyVo.setProjectLeaderInfo(userService.getStuRoughInfoById(project.getProjectLeaderId()));
        int projectAwardId = project.getProjectAwardId() == null ? StatusConstant.PROJECT_AWARD_ENCOURAGE_PRIZE.getCode() : project.getProjectAwardId();
        historyVo.setProjectAwardInfo(new StatusInfoVo(projectAwardId, StatusConvertUtil.convertProjectAwards(projectAwardId)));
        return historyVo;
    }

    /**
     * 转换评论->项目退回日志
     *
     * @param project
     * @return
     */
    public ProjectReturnLog convertCommentToProjectReturnLog(Project project, String comment, int userId){
        ProjectReturnLog projectReturnLog = new ProjectReturnLog();
        projectReturnLog.setProjectId(project.getProjectId());
        projectReturnLog.setCompId(project.getCompId());
        projectReturnLog.setStageId(project.getStageId());
        projectReturnLog.setReturnDate(new Date());
        projectReturnLog.setComment(comment);
        projectReturnLog.setUserId(userId);
        projectReturnLog.setRole(userRoleService.getRoleByUid(userId));
        return projectReturnLog;
    }

    /**
     * 转换项目退回日志 -> 审批信息
     *
     * @param projectReturnLog
     * @return
     */
    public ProjectReturnLogVo convertProjectReturnLogToProjectReturnLogVo(ProjectReturnLog projectReturnLog){
        ProjectReturnLogVo projectReturnLogVo = new ProjectReturnLogVo();
        BeanUtils.copyProperties(projectReturnLog, projectReturnLogVo);
        projectReturnLogVo.setOperatorInfo(userService.getUserRoughInfoById(projectReturnLog.getUserId()));
        projectReturnLogVo.setRoleInfo(userRoleService.getRoleInfoByRoleId(projectReturnLog.getRole()));
        return projectReturnLogVo;
    }

    /**
     * 转换项目列表为分页的审核信息
     *
     * @param projects
     * @param total
     * @return
     */
    public Map convertProjectsToRecommendVoPegeableMap(List<Project> projects, Long total){
        List<RecommendVo> recommendVoList = new ArrayList<>();
        projects.forEach(project -> {
            RecommendVo recommendVo = this.convertProjectToRecommandVo(project);
            recommendVoList.add(recommendVo);
        });
        return Map.of("data",recommendVoList,"total",total);
    }

    /**
     * 普通推荐项目
     *
     * @param projectId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public Integer normalRecProject(int projectId){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        Project project = projectMapper.selectById(projectId);
        //院级管理员视角置为 已审核
        project.setProjectAcademyStatus(StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_ALREADY_JUDGED.getCode());
        //拟推荐置为1
        project.setProjectSupposeSubmit(StatusConstant.PROJECT_ALREADY_SUPPOSE_SUBMIT.getCode() == 1);

        return projectMapper.update(project, new UpdateWrapper<Project>().eq("project_id",project.getProjectId()));
    }

    /**
     * 取消推荐
     *
     * @param projectId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public Integer cancelRec(int projectId){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        Project project = projectMapper.selectById(projectId);
        if(StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode().equals(project.getProjectAwardId())){
            // 自评三等奖：取消推荐 = 赛事奖励置为鼓励奖
            project.setProjectAwardId(StatusConstant.PROJECT_AWARD_ENCOURAGE_PRIZE.getCode());
        }else if(project.getProjectProvinceRec().equals(StatusConstant.PROJECT_IS_PROVINCE_REC.getCode() == 1)){
            // 省级直推： 取消推荐 = 是否省级直推置为0 + 拟推荐置为0
            project.setProjectSupposeSubmit(StatusConstant.PROJECT_NOT_SUPPOSE_SUBMIT.getCode() == 1);
            project.setProjectProvinceRec(StatusConstant.PROJECT_IS_NOT_PROVINCE_REC.getCode() == 1);
        }else{
            // 普通推荐： 取消推荐 = 是否拟推荐项目变为0
            project.setProjectSupposeSubmit(StatusConstant.PROJECT_NOT_SUPPOSE_SUBMIT.getCode() == 1);
        }
        return projectMapper.update(project, new UpdateWrapper<Project>().eq("project_id",project.getProjectId()));
    }

    /**
     * 省级推荐
     *
     * @param projectId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public Integer recProvinceProject(int projectId) {
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        Project project = projectMapper.selectById(projectId);
        //院级管理员视角置为 已审核
        project.setProjectAcademyStatus(StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_ALREADY_JUDGED.getCode());
        //是否省级推荐设为1
        project.setProjectProvinceRec(StatusConstant.PROJECT_IS_PROVINCE_REC.getCode() == 1);
        //拟推荐置为1
        project.setProjectSupposeSubmit(StatusConstant.PROJECT_ALREADY_SUPPOSE_SUBMIT.getCode() == 1);
        return projectMapper.update(project, new UpdateWrapper<Project>().eq("project_id",project.getProjectId()));
    }

    /**
     * 自评三等奖
     *
     * @param projectId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public Integer academyThirdPrizeProject(int projectId) {
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        Project project = projectMapper.selectById(projectId);
        //院级管理员视角置为 已审核
        project.setProjectAcademyStatus(StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_ALREADY_JUDGED.getCode());
        //获奖等级置为三等奖
        project.setProjectAwardId(StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode());
        return projectMapper.update(project, new UpdateWrapper<Project>().eq("project_id",project.getProjectId()));
    }

    /**
     * 获得拟推荐所有项目
     *
     * @param academyId
     * @return
     */
    public List<Project> getAlreadyRecProjects(int academyId, int compId) {
        //根据当前时间获取stageId
        Integer stageId = competitionService.getStageIdByTime(compId);
        return projectMapper.selectList(new QueryWrapper<Project>().eq("comp_id", compId).eq("stage_id", stageId).eq("project_academy_id", academyId).eq("project_suppose_submit", StatusConstant.PROJECT_ALREADY_SUPPOSE_SUBMIT.getCode()).eq("project_delete_status",StatusConstant.PROJECT_NOT_DELETE.getCode()));
    }

    /**
     * 根据比赛年份与赛事类型、学院Id获取学院赛事结果
     *
     * @param compYear
     * @param compType
     * @param academyId
     * @param stageId
     * @return
     */
    public List<HistoryVo> getHistory(int compYear, int compType, Integer academyId, int stageId){
        List<Project> projects = projectMapper.selectHistory(compYear, compType, academyId, stageId);
        List<HistoryVo> historyVoList = new ArrayList<>();
        projects.forEach(project -> {
            RecommendVo recommendVo = this.convertProjectToRecommandVo(project);
            HistoryVo historyVo = this.convertProjectToHistoryVo(project);
            historyVoList.add(historyVo);
        });
        return historyVoList;
    }

    /**
     * 已审核接口
     *
     * @param projectId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public Integer judgeProject(int projectId) {
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        Project project = projectMapper.selectById(projectId);
        project.setProjectAwardId(StatusConstant.PROJECT_AWARD_ENCOURAGE_PRIZE.getCode());
        project.setProjectAcademyStatus(StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_ALREADY_JUDGED.getCode());
        return projectMapper.update(project, new UpdateWrapper<Project>().eq("project_id",project.getProjectId()));
    }

    /**
     * 增加院级管理员备注
     *
     * @param note
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public int addNote(int projectId, String note){
        if(projectMapper.selectCount(new QueryWrapper<Project>().eq("project_id", projectId))<1){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        Project project = projectMapper.selectById(projectId);
        project.setProjectAcademyNote(note);
        return projectMapper.update(project, new UpdateWrapper<Project>().eq("project_id",project.getProjectId()));
    }

    /**
     * 获取院级管理员备注
     *
     * @param projectId
     * @return
     */
    public String getNote(int projectId){
        return projectMapper.selectById(projectId).getProjectAcademyNote();
    }

    /**
     * 获取学校管理员已经推荐校团委项目数量（不需要评委）
     *
     * @param stageId
     * @return
     */
    public int getSchoolAlreadyRecNum(int stageId){
        return projectMapper.getSchoolAlreadyRecNum(stageId);
    }

    /**
     * 获取校团委项目报名到校级管理员处的数量
     *
     * @param stageId
     * @return
     */
    public int getSchoolEnrollNum(int stageId){
        return projectMapper.selectCount(new QueryWrapper<Project>().eq("stage_id", stageId).eq("project_school_rec", StatusConstant.PROJECT_IS_SCHOOL_COMMUNITY_REC.getCode())
                .eq("project_delete_status", StatusConstant.PROJECT_NOT_DELETE.getCode()).ne("project_school_status", StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_INVISIBLE.getCode()));
    }

    /**
     * 获取直推省级报名到校级管理员处的数量
     *
     * @param stageId
     * @return
     */
    public int getProvinceRecEnrollNum(int stageId){
        return projectMapper.selectCount(new QueryWrapper<Project>().eq("stage_id", stageId).eq("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode())
                .eq("project_delete_status", StatusConstant.PROJECT_NOT_DELETE.getCode()).ne("project_school_status", StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_INVISIBLE.getCode()));
    }

    /**
     * 获取学校管理员已经审核省级数量（需要评委）
     *
     * @param stageId
     * @return
     */
    public Integer getDirectProvinceAlreadyRecNum(int stageId){
        return projectMapper.getDirectProvinceAlreadyRecNum(stageId);
    }

    /**
     * 校级管理员-获取学院已推荐项目数量
     *
     * @param stageId
     * @return
     */
    public int getAcademyAlreadyRecNum(int stageId, int academyId){
        return projectMapper.selectCount(
                new QueryWrapper<Project>()
                        .eq("project_delete_status", StatusConstant.PROJECT_NOT_DELETE.getCode() == 1)
                        .eq("stage_id", stageId)
                        .eq("project_academy_id", academyId)
                        .eq("project_suppose_submit", StatusConstant.PROJECT_ALREADY_SUPPOSE_SUBMIT.getCode() == 1)
                        .ne("project_award_id", StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode())
                        .ne("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode() == 1)
                        .ne("project_school_rec", StatusConstant.PROJECT_IS_SCHOOL_COMMUNITY_REC.getCode() == 1)
        );
    }

    /**
     * 校级管理员-获取学院已审核项目数量
     *
     * @param stageId
     * @return
     */
    public int getAcademyAlreadyCheckNum(int stageId, int academyId){
        return projectMapper.selectCount(
                new QueryWrapper<Project>()
                        .eq("project_delete_status", StatusConstant.PROJECT_NOT_DELETE.getCode() == 1)
                        .eq("stage_id", stageId)
                        .eq("project_academy_id", academyId)
                        .eq("project_academy_status", StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_ALREADY_JUDGED.getCode())
                        .ne("project_award_id", StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode())
                        .ne("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode() == 1)
                        .ne("project_school_rec", StatusConstant.PROJECT_IS_SCHOOL_COMMUNITY_REC.getCode() == 1)
        );
    }

    /**
     * 校级管理员-获取学校已审核项目数量
     *
     * @param stageId
     * @return
     */
    public int getSchoolRecPassNum(int stageId, int academyId){
        return projectMapper.selectCount(
                new QueryWrapper<Project>()
                        .eq("project_delete_status", StatusConstant.PROJECT_NOT_DELETE.getCode() == 1)
                        .eq("stage_id", stageId)
                        .eq("project_academy_id", academyId)
                        .eq("project_school_status", StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_ALREADY_JUDGED.getCode())
                        .ne("project_award_id", StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode())
                        .ne("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode() == 1)
                        .ne("project_school_rec", StatusConstant.PROJECT_IS_SCHOOL_COMMUNITY_REC.getCode() == 1)
        );
    }

    /**
     * 获取校级管理员视角 普通项目报名数量
     *
     * @param stageId
     * @return
     */
    public int getSchoolNormalProjectsEnroll(int stageId, int academyId){
        return projectMapper.selectCount(
                new QueryWrapper<Project>()
                        .eq("project_delete_status", StatusConstant.PROJECT_NOT_DELETE.getCode() == 1)
                        .eq("stage_id", stageId)
                        .eq("project_academy_id", academyId)
                        .ne("project_school_status", StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_INVISIBLE.getCode())
                        .ne("project_award_id", StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode())
                        .ne("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode() == 1)
                        .ne("project_school_rec", StatusConstant.PROJECT_IS_SCHOOL_COMMUNITY_REC.getCode() == 1)
        );
    }

    /**
     * 校级管理员获取审核项目列表
     *
     * @param academyId
     * @return
     */
    public Map getWaitingForJudgeProjectInfo(int academyId, int compId, int stageId, int pageNum, int pageSize){
//        Integer stageIdByTime = competitionService.getStageIdByTime(compId);
        Page<Project> projectPage = projectMapper.selectPage(new Page<>(pageNum, pageSize),
                new QueryWrapper<Project>().eq("comp_id",compId)
                        .eq("stage_id",stageId)
                        .eq("project_academy_id", academyId)
                        .eq("project_delete_status", StatusConstant.PROJECT_NOT_DELETE.getCode())
                        .ne("project_school_status", StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_INVISIBLE.getCode())
                        .ne("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode())
                        .ne("project_school_rec",StatusConstant.PROJECT_IS_SCHOOL_COMMUNITY_REC.getCode())
                        .orderByDesc("project_school_status", "project_create_time"));
        return this.convertProjectsToRecommendVoPegeableMap(projectPage.getRecords(), projectPage.getTotal());
    }

    /**
     * 获取校团委推荐项目
     *
     * @return
     */
    public Map getSchoolCommunityRecProjectInfo(int compId, int stageId, int pageNum, int pageSize){
//        Integer stageIdByTime = competitionService.getStageIdByTime(compId);
        Page<Project> projectPage = projectMapper.selectPage(new Page<>(pageNum, pageSize), new QueryWrapper<Project>().eq("comp_id",compId).eq("stage_id",stageId).eq("project_school_rec", StatusConstant.PROJECT_IS_SCHOOL_COMMUNITY_REC.getCode()).eq("project_delete_status",StatusConstant.PROJECT_NOT_DELETE.getCode()).ne("project_school_status", StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_INVISIBLE.getCode()).orderByDesc("project_school_status","project_create_time"));
        return this.convertProjectsToRecommendVoPegeableMap(projectPage.getRecords(), projectPage.getTotal());
    }

    /**
     * 获取省级直推推荐项目
     *
     * @return
     */
    public Map getProvinceRecProjectInfo(int compId, int stageId, int pageNum, int pageSize){
//        Integer stageIdByTime = competitionService.getStageIdByTime(compId);
        Page<Project> projectPage = projectMapper.selectPage(new Page<>(pageNum, pageSize), new QueryWrapper<Project>().eq("comp_id",compId).eq("stage_id",stageId).eq("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode()).eq("project_delete_status",StatusConstant.PROJECT_NOT_DELETE.getCode()).ne("project_school_status", StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_INVISIBLE.getCode()).orderByDesc("project_school_status","project_create_time"));
        return this.convertProjectsToRecommendVoPegeableMap(projectPage.getRecords(), projectPage.getTotal());
    }

    /**
     * 批量审核项目
     *
     * @param projectIds
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public int judgeProjects(String[] projectIds){
        for(String projectId : projectIds){
            Project project = projectMapper.selectById(Integer.parseInt(projectId));
            project.setProjectSchoolStatus(StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_ALREADY_JUDGED.getCode());
            projectMapper.updateById(project);
        }
        return projectIds.length;
    }

    /**
     * 获得评委应评审项目总数
     *
     * @param compId
     * @param stageId
     * @param tag
     * @return
     */
    public int getJudgeTaskNum(int compId, int stageId, String tag){
        //增加省级直推不应该被评委评审逻辑,修改校级管理员状态应该是退回修改和已审核
        return projectMapper.selectCount(new QueryWrapper<Project>().eq("comp_id",compId)
                .eq("stage_id", stageId)
                .eq("project_tag",tag)
                .eq("project_delete_status",StatusConstant.PROJECT_NOT_DELETE.getCode())
                .in("project_school_status", StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_ALREADY_JUDGED.getCode(), StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_RETURN_FOR_MODIFY.getCode())
                .eq("project_province_rec", false)
                .ne("project_award_id", StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode()));
    }

    /**
     * 根据竞赛类型获取distinct竞赛标签信息
     */
    @Cacheable(value = "NoExpire", key = "'comp_distinct_tag_list_'+#compId + #stageId")
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public List<Object> getDistinctCompTags(int compId, int stageId){
        return projectMapper.selectObjs(new QueryWrapper<Project>().select("distinct project_tag")
                .eq("comp_id", compId)
                .eq("stage_id", stageId)
                .ne("project_award_id", StatusConstant.PROJECT_AWARD_ACADEMY_THIRD_PRIZE.getCode())
                .ne("project_province_rec", true));
    }

    /**
     * 根据ID获取项目信息
     *
     * @param id
     * @return
     */
    public Project getProjectById(int id){
        Project project = projectMapper.selectById(id);
        if(project == null){
            throw new AppException(ErrorCode.PROJECT_NOT_EXIST);
        }
        return project;
    }

    /**
     * 退回修改项目提交
     *
     * @param projectId
     * @param stageId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int submitReturnedProject(int projectId, int stageId){
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("project_id", projectId);
        updateWrapper.eq("stage_id", stageId);
        updateWrapper.set("project_student_status", StatusConstant.PROJECT_STUDENT_STATUS_SUBMITTED.getCode());

        //获得最新退回修改的操作员等级
        if(StatusConstant.IDENTITY_SCHOOL_ADMIN.getCode() == (projectReturnLogService.getNewestProjectReturnLog(projectId, stageId).getRole())){
            //校级管理员退回则  项目校级状态设为未审核， 项目院级状态设为已审核
            updateWrapper.set("project_school_status", StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_WAIT_FOR_JUDGE.getCode());
            updateWrapper.set("project_academy_status", StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_ALREADY_JUDGED.getCode());
        }else{
            //院级管理员退回则  项目院级状态设为待审核
            updateWrapper.set("project_academy_status", StatusConstant.PROJECT_STATUS_ACADEMY_VERSION_WAIT_FOR_JUDGE.getCode());
        }
        return projectMapper.update(null,updateWrapper );
    }

    /**
     * 获取退回修改项目的审批信息
     *
     * @param projectId
     * @param stageId
     * @return
     */
    public ProjectReturnLogVo getReturnedOA(int projectId, int stageId){
        ProjectReturnLog newestProjectReturnLog = projectReturnLogService.getNewestProjectReturnLog(projectId, stageId);
        return this.convertProjectReturnLogToProjectReturnLogVo(newestProjectReturnLog);
    }

    /**
     * 批量增加推荐项目进入下一个阶段
     *
     * @param projectIds
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public Integer recProjectNextStageInBatch(List<Integer> projectIds){
        Integer affectRows = 0;
        for (Integer projectId : projectIds) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("project_id", projectId);
            updateWrapper.set("project_enter_next_stage", StatusConstant.PROJECT_PERMITTED_ENTER_NEXT_STAGE.getCode());
            affectRows += projectMapper.update(null,updateWrapper );
        }
        return affectRows;
    }

    /**
     * 根据阶段Id和组名获取项目粗略信息
     *
     * @param stageId
     * @param groupName
     */
    public PageVo<List<JudgeProjectRoughInfoVo>> getProjectRoughPageableByGroupExceptProvinceRec(int stageId, String groupName, int pageNum, int pageSize, int judgeId){
        List<String> tags = judgeProjectDistributionService.getJudgeProjectDistributionByJudgeId(judgeId).stream().map(judgeProjectDistribution -> {
            return judgeProjectDistribution.getTag();
        }).collect(Collectors.toList());
        Page<Project> projectPage =  projectMapper.selectPage(new Page<>(pageNum, pageSize), new QueryWrapper<Project>().in("project_tag", tags).ne("project_province_rec", StatusConstant.PROJECT_IS_PROVINCE_REC.getCode() == 1).eq("stage_id", stageId).eq("project_group", groupName).eq("project_school_status", StatusConstant.PROJECT_STATUS_SCHOOL_VERSION_ALREADY_JUDGED.getCode()));
        List<JudgeProjectRoughInfoVo> judgeProjectRoughInfoVos = projectPage.getRecords().stream().map(project -> {
            JudgeProjectRoughInfoVo judgeProjectRoughInfoVo = new JudgeProjectRoughInfoVo();
            BeanUtils.copyProperties(project, judgeProjectRoughInfoVo);
            ProjectScore projectScore = projectScoreService.getProjectScoreByJudgeIdAndProjectId(stageId, judgeId, project.getProjectId());
            judgeProjectRoughInfoVo.setScore(projectScore == null ? null : projectScore.getScore());
            judgeProjectRoughInfoVo.setProjectLeaderInfo(userService.getStuRoughInfoById(project.getProjectLeaderId()));
            return judgeProjectRoughInfoVo;
        }).collect(Collectors.toList());
        return new PageVo<>(projectPage.getCurrent(), projectPage.getSize(), judgeProjectRoughInfoVos, projectPage.getTotal());
    }

    /**
     * 根据leader id查询该用户所有项目Id
     *
     * @param userId
     * @return
     */
    public List<Object> getProjectIdsByLeaderId(int userId){
        return projectMapper.selectObjs(new QueryWrapper<Project>().eq("project_leader_id", userId).select("project_id"));
    }

    /**
     * 根据academy id查询该用户所有项目Id
     *
     * @param academyId
     * @return
     */
    public List<Object> getProjectIdsByAcademyId(int academyId){
        return projectMapper.selectObjs(new QueryWrapper<Project>().eq("project_academy_id", academyId).select("project_id"));
    }

    /**
     * 根据项目ID获取均分
     */
    public Object getAvgScore(int projectId){
        return projectMapper.selectObjs(new QueryWrapper<Project>().eq("project_id", projectId).select("project_score")).get(0);
    }

    /**
     * 项目进入下一个阶段
     *
     * @param projectId
     * @param stageId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public Integer projectEnterNextStage(int projectId, int stageId){
        Project project = this.getProjectById(projectId);
        ProjectDto projectDto = ProjectDto.builder()
                .projectAcademyId(project.getProjectAcademyId())
                .projectGroup(project.getProjectGroup())
                .projectName(project.getProjectName())
                .memberDtos(BeanUtil.copyListProperties(projectMemberService.getMemberRough(projectId), ProjectMemberDto::new))
                .projectProvinceRec(project.getProjectProvinceRec())
                .projectTag(project.getProjectTag())
                .projectSchoolRec(project.getProjectSchoolRec())
                .projectAcademyNote(project.getProjectAcademyNote())
                .build();
        Integer newProjectId = this.addProjectAndAuthor(projectDto, project.getProjectLeaderId(), project.getCompId(), stageId);

        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("project_id", projectId);
        updateWrapper.set("project_enter_next_stage", StatusConstant.PROJECT_ENTERED_NEXT_STAGE.getCode());
        projectMapper.update(null,updateWrapper);

        return newProjectId;
    }
}